#include "MQTTClient.h"
#include "log/log.h"
#include "app_common.h"
//这里协议要选择tcp,因为mqtt不支持，mqtt是基于tcp实现的,所以这里选择tcp
#define SERVER_URL "tcp://192.168.56.33:1883" //对应的mosquitto服务器ip
#define CLINET_ID "my_client" //也可以用UUID，保证唯一,这里简单点
#define TOPIC_PULL "topic_pull" // 拉取  订阅主题
#define TOPIC_PUSH "topic_push" // 推送  发布主题
void MQTTClient_Conn_Lost(void *, char *);
int MQTTClient_Message_Arrived(void *, char *, int, MQTTClient_message *);
void MQTTClient_Delivery_Complete(void *, MQTTClient_deliveryToken);

typedef struct
{
    MQTTClient client;
} app_mqtt_t;
static app_mqtt_t mqtt_ctx;

Com_State app_mqtt_init(void)
{
    // 1. 创建MQTT客户端
    if (MQTTClient_create(&mqtt_ctx.client,
                          SERVER_URL,
                          CLINET_ID,
                          MQTTCLIENT_PERSISTENCE_NONE,
                          NULL) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTT Create Fail!");
        return COM_ERROR;
    }
    // 2. 设置回调函数
    if (MQTTClient_setCallbacks(mqtt_ctx.client,
                                NULL,
                                MQTTClient_Conn_Lost,
                                MQTTClient_Message_Arrived,
                                MQTTClient_Delivery_Complete) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTT setCallbacks Fail!");
        return COM_ERROR;
    }
    // 3. 连接服务器
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    if (MQTTClient_connect(mqtt_ctx.client, &conn_opts) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTT connect Fail!");
        return COM_ERROR;
    }
    log_info("MQTT connect success");
    // 4. 订阅主题
    if (MQTTClient_subscribe(mqtt_ctx.client, TOPIC_PULL, 0) != MQTTCLIENT_SUCCESS)
    {
         log_error("MQTT subscribe Fail!");
        return COM_ERROR;
    }
    log_info("MQTT subscribe success ,topic:%s" ,TOPIC_PULL);
    return COM_OK;
}

/**
 * @brief 丢失连接回调函数
 *
 * @param context
 * @param cause
 */

void MQTTClient_Conn_Lost(void *context, char *cause)
{
    log_error("Connect lost:%s" , cause);
}
/**
 * @brief 收到消息回调函数
 *
 * @param context
 * @param topicName
 * @param topicLen
 * @param message
 * @return int
 */
/**This function must return 0 or 1 indicating whether or not
 * the message has been safely received by the client application. <br>
 * Returning 1 indicates that the message has been successfully handled.
 * To free the message storage, ::MQTTClient_freeMessage must be called.
 * To free the topic name storage, ::MQTTClient_free must be called.<br>
 * Returning 0 indicates that there was a problem. In this
 * case, the client library will reinvoke MQTTClient_messageArrived() to
 * attempt to deliver the message to the application again.
 * Do not free the message and topic storage when returning 0, otherwise
 * the redelivery will fail.
 */
int MQTTClient_Message_Arrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    log_info("Message arrived:%.*s ",message->payloadlen , message->payload );

    MQTTClient_freeMessage(&message );
    MQTTClient_free(topicName);
    return 1; //重要，根据文档说明
}
/**
 * @brief 发送完成回调函数
 *
 * @param context
 * @param dt
 */
void MQTTClient_Delivery_Complete(void *context, MQTTClient_deliveryToken dt)
{
     log_info("Message Deliver:%d" ,dt);
}

int main()
{
    app_mqtt_init();
    return 0;
}